-------------------------------------------------
--  utils.lua
--  Created by DX on 17-3-31.
--  Fixed by .
-------------------------------------------------
utils = utils or {}

function utils.unescape(s)
	return UnityEngine.Networking..UnEscapeURL(s)
end
function utils.isEmpty(value)
	return value == nil or value == "" or tonumber(value) == 0 or type(value) == "userdata"-- or value==json.null
end

function utils.GetNumString(num)
	local len = string.len(tostring(num))
	if num < 10000 then
		return tostring(num)
	end
	if len < 8 and len>=5  then
		return string.sub(tostring(num),0,len-3).."K";
	end
	if len >= 8 then
		return string.sub(tostring(num),0,len-6).."M";
	else
		return tostring(num)
	end
end

function utils.GetNumString1(num)
	local len = string.len(tostring(num))
	if num < 1000000 then
		return tostring(num)
	else
		return string.sub(tostring(num),0,len-6).."M";
	end
end

function utils.IsAvailableGameObject(go)
	return go and go:Equals(nil) == false
end

function utils.GetNumString2(num,isceil)
	local _num = math.floor(num)
	if isceil then
		local  _num = math.ceil(num)
	end
	local len = string.len(tostring(_num))
	if _num < 10000 then
		return tostring(_num)
	end
	if len < 8 and len>=5  then
		return string.sub(tostring(_num),0,len-3).."K";
	end
	if len >= 8 then
		return string.sub(tostring(_num),0,len-6).."M";
	else
		return tostring(_num)
	end
end

function utils.PrintGC(self)
	print(self.__cname ..' Register GC Print')
	local function setmt__gc(t, mt)
		local prox = newproxy(true)
		getmetatable(prox).__gc = function() mt.__gc(t) end
		t[prox] = true
		return setmetatable(t, mt)
	end

	setmt__gc(self, {__gc = function()
		print('#########################GC######################')
	end})
end

function utils.parseParam(param)
	local t = {}
	local l = string.split(param, ";")
	for _,v in ipairs(l) do
		local p = string.split(v, "|")
		t[p[1]] = p[2]
	end
	return t
end

function utils.sort(list, funcs) --sortFuncs:[function(A, B)],func当A>B-> 1 A==B-> 0 A<B->-1 other->false,按照排序优先级排列
	local compareFunc = function(A, B)
		for _, func in ipairs(funcs) do
			local ret = func(A, B)
			if ret ~= 0 then
				return ret
			end
		end

		return 0
	end

	local partition = function (array, left, right, pivotIndex)
		local pivotValue = array[pivotIndex]
		array[pivotIndex], array[right] = array[right], array[pivotIndex]

		local storeIndex = left

		for i =  left, right-1 do
			if compareFunc(array[i], pivotValue) <= 0 then
				array[i], array[storeIndex] = array[storeIndex], array[i]
				storeIndex = storeIndex + 1
			end
		end
		array[storeIndex], array[right] = array[right], array[storeIndex]

		return storeIndex
	end

	local quicksort = nil
	quicksort = function (array, left, right)
		if right > left then
			local pivotNewIndex = partition(array, left, right, left)
			quicksort(array, left, pivotNewIndex - 1)
			quicksort(array, pivotNewIndex + 1, right)
		end
	end

	--local function bubbleSort(A)
	--	local itemCount=#A
	--	local hasChanged
	--	repeat
	--		hasChanged = false
	--		itemCount=itemCount - 1
	--		for i = 1, itemCount do
	--			if compareFunc(A[i], A[i + 1]) > 0 then
	--				A[i], A[i + 1] = A[i + 1], A[i]
	--				hasChanged = true
	--			end
	--		end
	--	until hasChanged == false
	--end

	quicksort(list, 1, #list)
end

function utils.stableSort(array, funcs)
	local compareFunc = function(A, B)
		for _, func in ipairs(funcs) do
			local ret = func(A, B)
			if ret ~= 0 then
				return ret
			end
		end

		return 0
	end

	local temp = {unpack(array)}

	local function mergeHalves(first, last)
		local left = first
		local leftTail = math.floor((first + last) / 2)
		local right = leftTail + 1

		-- Compare left and right halves of array, sort into temp --
		for i = first, last do
			if (right > last or (compareFunc(array[left], array[right]) <= 0 and left <= leftTail)) then
				temp[i] = array[left]
				left = left + 1
			else
				temp[i] = array[right]
				right = right + 1
			end
		end

		-- Copy sorted section back to array --
		for i = first, last do
			array[i] = temp[i]
		end
	end

	local function sort(first, last)
		-- Size == 1 --
		if first >= last then return end

		-- Split & sort halves recursively --
		local middle = math.floor((first + last) / 2)

		sort(first, middle)
		sort((middle+1), last)

		mergeHalves(first, last)
	end

	-- Default: sort entire array --
	local first = 1
	local last = #array

	sort(first, last)
end

function utils.step(A, B)
	if type(A) ~= type(B) then
		error('不使用一种类型不能相互比较')
	end

	if type(A) == 'boolean' then
		if A and not B then
			return 1
		elseif not A and B then
			return -1
		else
			return 0
		end
	elseif type(A) == 'number' then
		if A > B then
			return 1
		elseif A < B then
			return -1
		else
			return 0
		end
	end
end

function utils.uiPos2WorldPos(mainCamera, rootCanvas, rtf, distance)
	local screenPos = UnityEngine.RectTransformUtility.WorldToScreenPoint(rootCanvas.worldCamera, rtf.position)
	screenPos.z = distance
	local pos = mainCamera:ScreenToWorldPoint(screenPos);
	return pos
end

function utils.checkSameRace(race1,race2,_race1,_race2)
	return race1==_race1 or race1==_race2 or (race2~=nil and race2>0 and (race2==_race1 or race2==_race2))
end

function utils.setLayer(trans,layer)
	if trans and utils.IsAvailableGameObject(trans.gameObject) then
		trans.gameObject.layer = layer
		for index = 0,trans.childCount-1 do
			utils.setLayer(trans:GetChild(index),layer)
		end
	end
end

function utils.SubStringUTF8(str, startIndex, endIndex)
	if startIndex < 0 then
		startIndex = utils.SubStringGetTotalIndex(str) + startIndex + 1;
	end

	if endIndex ~= nil and endIndex < 0 then
		endIndex = utils.SubStringGetTotalIndex(str) + endIndex + 1;
	end

	if endIndex == nil then
		return string.sub(str, utils.SubStringGetTrueIndex(str, startIndex));
	else
		return string.sub(str, utils.SubStringGetTrueIndex(str, startIndex), utils.SubStringGetTrueIndex(str, endIndex + 1) - 1);
	end
end

--返回从1开始字符长度限制为n的字符串
function utils.GetSubStringByByteCount(str,n)
	local curIndex = 0;
	local i = 1;
	local lastCount = 1;
	repeat
		lastCount = utils.SubStringGetByteCount(str, i)
		i = i + lastCount;
		curIndex = curIndex + 1;

	until(n + 1< i or lastCount == 0);
	local res = utils.SubStringUTF8(str, 1, curIndex - 1)
	if #str > n then
		res = res .. "..."
	end
	return res
end

--获取中英混合UTF8字符串的真实字符数量
function utils.SubStringGetTotalIndex(str)
	local curIndex = 0;
	local i = 1;
	local lastCount = 1;
	repeat
		lastCount = utils.SubStringGetByteCount(str, i)
		i = i + lastCount;
		curIndex = curIndex + 1;
	until(lastCount == 0);
	return curIndex - 1;
end

function utils.SubStringGetTrueIndex(str, index)
	local curIndex = 0;
	local i = 1;
	local lastCount = 1;
	repeat
		lastCount = utils.SubStringGetByteCount(str, i)
		i = i + lastCount;
		curIndex = curIndex + 1;
	until(curIndex >= index);
	return i - lastCount;
end

--返回当前字符实际占用的字符数
function utils.SubStringGetByteCount(str, index)
	local curByte = string.byte(str, index)
	local byteCount = 1;
	if curByte == nil then
		byteCount = 0
	elseif curByte > 0 and curByte <= 127 then
		byteCount = 1
	elseif curByte>=192 and curByte<=223 then
		byteCount = 2
	elseif curByte>=224 and curByte<=239 then
		byteCount = 3
	elseif curByte>=240 and curByte<=247 then
		byteCount = 4
	end
	return byteCount;
end


function utils.GetModelShowPath(modelId)
	local path = "role_show" --config.HD and "role_show" or "low_role_show"
	local prefabPath = string.format('Res/Prefab/%s/%d_H/%d_H.prefab', path, modelId, modelId)
	return prefabPath
end


function utils.power(hp, attack, def, mdef)
	local v = hp*0.2+attack*3+def+mdef
	return v
end


function utils.worldPosition2UIPosition(uiTf, worldPosition)
	if UnityEngine.Camera==nil then return Vector2.zero end
    local pos = UnityEngine.Camera.main:WorldToScreenPoint(worldPosition)
	local success, anchoredPosition = UnityEngine.RectTransformUtility.ScreenPointToLocalPointInRectangle(uiTf, pos, VIEWM.GuiCameraComponent, Vector2.zero)
	if success then
		return anchoredPosition
	end
	return Vector2.zero
end

function utils.isAI(userId)
	return userId>=900000 and userId<=1000000
end

function utils.getFestivalArenaDefendSetType(dan)
    if dan<=2 then
        return 1
    elseif dan<=4 then
        return 2
    else
        return 3
    end
end
function utils.getFestivalArenaDefendTeamIdList(defendSetType)
    local list
    if defendSetType==1 then
        list = {1}
    elseif defendSetType==2 then
        list = {11, 12, 13}
    else
        list = {21, 22, 23}
    end
    return list
end
function utils.getFestivalArenaMaxTeamCount(defendSetType)
	local teamIdList = utils.getFestivalArenaDefendTeamIdList(defendSetType)
	return #teamIdList
end
function utils.festivalArenaTeamId2FormationIndex(teamId)
    return teamId%10
end
function utils.festivalArenaFormationIndex2TeamId(defendSetType, formationIndex)
	local teamIdList = utils.getFestivalArenaDefendTeamIdList(defendSetType)
	return teamIdList[formationIndex]
end

function utils.GetTopArenaTurnName(turn)
	if turn == 1 then
		return LanModel.GetTextByID(580018)
	elseif turn == 2 then
		return LanModel.GetTextByID(580021)
	elseif turn == 3 then
		return LanModel.GetTextByID(580022)
	elseif turn == 4 then
		return LanModel.GetTextByID(580023)
	elseif turn == 5 then
		return LanModel.GetTextByID(580024)
	elseif turn == 6 then
		return LanModel.GetTextByID(580025)
	elseif turn == 7 then
		return LanModel.GetTextByID(580026)
	end
	return ""
end

function utils.ReqUtilsWaitAsync(min,max)
	math.randomseed(tostring(TimeModel.GetServerTime()):reverse():sub(1,6))
	local num = math.random(min,max)
	coroutine.wait(num)
end

function utils.GetRandom(min,max)
	math.randomseed(tostring(TimeModel.GetServerTime()):reverse():sub(1,6))
	return math.random(min,max)
end